package com.bt7274.scheduler;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bt7274.enums.PromotionType;
import com.bt7274.mapper.*;
import com.bt7274.pojo.*;
import com.bt7274.service.PromotionPolicyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 促销活动定时任务
 * 处理活动结束后的清理工作，如恢复用户默认促销策略等
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class PromotionScheduler {

    private final PromotionMapper promotionMapper;
    private final ActivityRecordMapper activityRecordMapper;
    private final UserExpMapper userExpMapper;
    private final PromotionPolicyService promotionPolicyService;

    /**
     * 每小时执行一次，检查并处理已结束的促销活动
     */
    @Scheduled(cron = "0 0 * * * ?")
    @Transactional
    public void handleExpiredPromotions() {
        log.info("开始处理已结束的促销活动...");

        // 查找刚结束的活动（结束时间在过去1小时内）
        LocalDateTime oneHourAgo = LocalDateTime.now().minusHours(1);
        LocalDateTime now = LocalDateTime.now();

        QueryWrapper<Promotion> wrapper = new QueryWrapper<>();
        wrapper.eq("is_active", 1)
                .between("end_time", oneHourAgo, now);

        List<Promotion> expiredPromotions = promotionMapper.selectList(wrapper);

        for (Promotion promotion : expiredPromotions) {
            handleExpiredPromotion(promotion);
        }

        log.info("已结束的促销活动处理完成，共处理 {} 个活动", expiredPromotions.size());
    }

    /**
     * 处理单个已结束的促销活动
     */
    private void handleExpiredPromotion(Promotion promotion) {
        log.info("处理已结束活动: {} ({})", promotion.getTitle(), promotion.getId());

        // 获取促销类型
        PromotionType promotionType = PromotionType.getPromotionTypeByString(promotion.getType());

        // 根据活动类型进行不同的清理工作
        switch (promotionType) {
            case DOUBLE_UPLOAD:
            case FREE:
            case HALF_PRICE:
            case DOUBLE_DOWNLOAD:
            case DOUBLE_UPLOAD_DOWNLOAD:
                // 恢复参与该活动的用户的默认促销策略
                restoreUserDefaultPromotionPolicy(promotion);
                break;
            case NORMAL:
            default:
                // 普通类型的活动可能不需要特殊处理
                break;
        }
    }

    /**
     * 恢复用户的默认促销策略
     */
    private void restoreUserDefaultPromotionPolicy(Promotion promotion) {
        // 获取参与该活动的所有用户
        QueryWrapper<ActivityRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("promotion_id", promotion.getId());
        List<ActivityRecord> records = activityRecordMapper.selectList(wrapper);

        // 获取默认促销策略
        PromotionPolicy defaultPolicy = promotionPolicyService.getDefaultPromotionPolicy();
        if (defaultPolicy == null) {
            log.error("未找到默认促销策略");
            return;
        }

        int restoredCount = 0;
        for (ActivityRecord record : records) {
            UserExp userExp = userExpMapper.selectById(record.getUserId());
            if (userExp != null) {
                // 检查用户当前的促销策略是否是活动相关的
                PromotionPolicy currentPolicy = promotionPolicyService.getPromotionPolicyById(userExp.getPromotionPolicyId());
                PromotionType promotionType = PromotionType.getPromotionTypeByString(promotion.getType());
                if (currentPolicy != null && currentPolicy.getSlug().equalsIgnoreCase(promotionType.name())) {
                    // 恢复为默认策略
                    userExp.setPromotionPolicyId(defaultPolicy.getId());
                    userExpMapper.updateById(userExp);
                    restoredCount++;
                }
            }
        }

        log.info("活动 {} 结束，已恢复 {} 个用户的默认促销策略", promotion.getTitle(), restoredCount);
    }

    /**
     * 每天凌晨2点执行，统计促销活动效果
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void generatePromotionStatistics() {
        log.info("开始生成促销活动统计报告...");

        LocalDateTime yesterday = LocalDateTime.now().minusDays(1);

        // 统计昨天结束的活动
        QueryWrapper<Promotion> wrapper = new QueryWrapper<>();
        wrapper.between("end_time", yesterday.withHour(0).withMinute(0).withSecond(0),
                yesterday.withHour(23).withMinute(59).withSecond(59));

        List<Promotion> endedPromotions = promotionMapper.selectList(wrapper);

        for (Promotion promotion : endedPromotions) {
            generatePromotionReport(promotion);
        }

        log.info("促销活动统计报告生成完成");
    }

    /**
     * 生成单个活动的统计报告
     */
    private void generatePromotionReport(Promotion promotion) {
        // 统计参与人数
        QueryWrapper<ActivityRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("promotion_id", promotion.getId());
        Long participantCount = activityRecordMapper.selectCount(wrapper);

        // 统计奖励发放情况
        List<ActivityRecord> records = activityRecordMapper.selectList(wrapper);

        // 这里可以生成详细的报告并保存到数据库或发送给管理员
        log.info("活动统计 - {}: 参与人数={}, 开始时间={}, 结束时间={}",
                promotion.getTitle(), participantCount, promotion.getStartTime(), promotion.getEndTime());
    }

    /**
     * 每30分钟检查一次，自动激活即将开始的活动
     */
    @Scheduled(fixedDelay = 1800000) // 30分钟
    public void activateUpcomingPromotions() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime thirtyMinutesLater = now.plusMinutes(30);

        // 查找即将开始的活动（30分钟内）
        QueryWrapper<Promotion> wrapper = new QueryWrapper<>();
        wrapper.eq("is_active", 1)
                .between("start_time", now, thirtyMinutesLater);

        List<Promotion> upcomingPromotions = promotionMapper.selectList(wrapper);

        for (Promotion promotion : upcomingPromotions) {
            log.info("活动 {} 即将开始，准备时间: {}", promotion.getTitle(), promotion.getStartTime());
            // 这里可以发送通知给用户，告知活动即将开始
        }
    }
}
